using System;
using System.Collections;
using System.Collections.Generic;
using Iesi.Collections.Generic;

namespace Headspring.Training.Domain.Model
{
	public class Employee : IComparable<Employee>
	{
		private Guid _id;
		private string _userName;
		private string _firstName;
		private string _lastName;
		private string _emailAddress;
        private string _mobileNumber;
		private IDictionary<DayOfWeek, NotificationType> _preferences = getPopulatedSet();
		private ISet<JobRoleTenure> _jobRoles = new HashedSet<JobRoleTenure>();

		public Employee()
		{
		}

		public Employee(string userName, string firstName, string lastName, string emailAddress)
		{
			_userName = userName;
			_firstName = firstName;
			_lastName = lastName;
			_emailAddress = emailAddress;
		    _mobileNumber = string.Empty;
		}

        private static Dictionary<DayOfWeek, NotificationType> getPopulatedSet()
		{
            Dictionary<DayOfWeek, NotificationType> preferences = new Dictionary<DayOfWeek, NotificationType>();
			preferences.Add(DayOfWeek.Monday, NotificationType.Both);
			preferences.Add(DayOfWeek.Tuesday, NotificationType.Both);
			preferences.Add(DayOfWeek.Wednesday, NotificationType.Both);
			preferences.Add(DayOfWeek.Thursday, NotificationType.Both);
			preferences.Add(DayOfWeek.Friday, NotificationType.Both);
			preferences.Add(DayOfWeek.Saturday, NotificationType.SMS);
			preferences.Add(DayOfWeek.Sunday, NotificationType.SMS);
			return preferences;
		}

		public virtual Guid Id
		{
			get { return _id; }
			set { _id = value; }
		}

		public virtual string UserName
		{
			get { return _userName; }
			set { _userName = value; }
		}

		public virtual string FirstName
		{
			get { return _firstName; }
			set { _firstName = value; }
		}

		public virtual string LastName
		{
			get { return _lastName; }
			set { _lastName = value; }
		}

		public virtual string EmailAddress
		{
			get { return _emailAddress; }
			set { _emailAddress = value; }
		}

		public virtual string GetFullName()
		{
			return string.Format("{0} {1}", FirstName, LastName);
		}

		public override string ToString()
		{
			return GetFullName();
		}

		public int CompareTo(Employee other)
		{
			int compareResult = LastName.CompareTo(other.LastName);
			if(compareResult == 0)
			{
				compareResult = FirstName.CompareTo(other.FirstName);
			}

			return compareResult;
		}

	    private bool IsWeekend(DayOfWeek day)
	    {
	        return (day == DayOfWeek.Saturday || day == DayOfWeek.Sunday);
	    }

	    private bool IsWeekday(DayOfWeek day)
	    {
            return (day != DayOfWeek.Saturday && day != DayOfWeek.Sunday);
	    }

	    public virtual string MobileNumber
	    {
	        get { return _mobileNumber; }
	        set
	        {
	            long mobileNumber;
                if (long.TryParse(value, out mobileNumber))
                {
                    _mobileNumber = value;
                }
                else
                {
                    throw new InvalidOperationException("Invalid mobile number");
                }
	        }
	    }

		public virtual NotificationType GetNotificationTypeFor(DayOfWeek dayOfWeek)
		{
			return _preferences[dayOfWeek];
		}

		public virtual void SetNotificationPreferenceFor(DayOfWeek dayOfWeek, NotificationType notificationType)
		{
			_preferences[dayOfWeek] = notificationType;
		}

		public virtual void SetAllNotificationPreferencesTo(NotificationType notificationType)
		{
			_preferences.Clear();
			_preferences.Add(DayOfWeek.Monday, notificationType);
			_preferences.Add(DayOfWeek.Tuesday,(notificationType));
			_preferences.Add(DayOfWeek.Wednesday, notificationType);
			_preferences.Add(DayOfWeek.Thursday,notificationType);
			_preferences.Add(DayOfWeek.Friday, notificationType);
			_preferences.Add(DayOfWeek.Saturday, notificationType);
			_preferences.Add(DayOfWeek.Sunday, notificationType);
		}

		public virtual void AddJobRole(JobRoleTenure tenure)
		{
			_jobRoles.Add(tenure);
		}

		public virtual JobRoleTenure[] GetJobRoles()
		{
			List<JobRoleTenure> roles = new List<JobRoleTenure>(_jobRoles);
			return roles.ToArray();
		}
	}
}